package com.ym.controller.patient.pay;

import cn.hutool.core.date.DateUtil;
import com.ym.common.constant.Constants;
import com.ym.core.annotation.ApiSign;
import com.ym.core.annotation.Log;
import com.ym.core.domain.APIResponse;
import com.ym.core.domain.BaseController;
import com.ym.core.shiro.ShiroUtil;
import com.ym.core.utils.tkmybatis.TK;
import com.ym.medical.domain.bo.pay.WxApplyPaySign;
import com.ym.medical.domain.bo.pay.WxNotifyRespData;
import com.ym.medical.domain.entity.ConsumeDetailsEntity;
import com.ym.medical.domain.entity.InquiryOrderEntity;
import com.ym.medical.domain.param.OrderAndFileParam;
import com.ym.medical.domain.param.OrderParam;
import com.ym.medical.domain.vo.MindListMobileVO;
import com.ym.medical.enums.InquiryOrderStateEnum;
import com.ym.medical.enums.OrderFlowRecordSatusEnum;
import com.ym.medical.service.IConsumeDetailsSV;
import com.ym.medical.service.IInquiryOrderSV;
import com.ym.medical.service.IMindSV;
import com.ym.medical.service.IOrderPaySV;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

/**
 * 患者端-订单相关
 *
 * @author: DaiKuangYin
 * @version: 2019年07月15日 10:15
 */
@Api(tags = "患者端-订单相关")
@RestController
@ApiSign
@RequestMapping(value = "/patient/order", headers = Constants.Api.VERSION)
public class OrderPayController extends BaseController {


    private static final Logger LOGGER = LoggerFactory.getLogger(OrderPayController.class);

    @Autowired
    private IInquiryOrderSV inquiryOrderSV;

    @Autowired
    private IOrderPaySV orderPaySV;

    @Autowired
    private IConsumeDetailsSV consumeDetailsSV;

    @Autowired
    private IMindSV mindSV;

    @Log
    @ApiOperation("订单-微信支付申请")
    @PostMapping(value = "/pay/mini", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiSign(isSign = false)
    public APIResponse miniPay(@RequestBody OrderParam orderModel) {
        WxApplyPaySign.SignData data = orderPaySV.payApply(orderModel);
        return successData(data);
    }

    @ApiOperation("订单-账户余额支付")
    @PostMapping(value = "/pay/account", consumes = MediaType.APPLICATION_JSON_VALUE)
    public APIResponse accountPay(@RequestBody OrderParam orderModel, HttpServletRequest request) throws Exception {
        orderPaySV.accountPay(orderModel);
        return successMsg("账户余额支付成功");
    }


    @Log
    @ApiOperation("回调支付修改订单信息")
    @RequestMapping(value = "/orderPayCallBack", method = RequestMethod.POST)
    public APIResponse orderPayCallBack(@RequestBody @Valid WxNotifyRespData wxNotifyRespData) throws Exception {
        InquiryOrderEntity order = inquiryOrderSV.selectOne(InquiryOrderEntity.builder().ioNum(wxNotifyRespData.getIoNum()).build());
        order.setPaymentTime(DateUtil.parse(wxNotifyRespData.getTimeEnd(), "yyyyMMddHHmmss"));
        orderPaySV.updateOrderInfo(order, wxNotifyRespData.getTransactionId());
        return success();
    }

    @Log(dataBase = false, printBody = false)
    @ApiOperation("订单-根据订单号获取订单信息")
    @GetMapping(value = "/ioNum", consumes = MediaType.APPLICATION_JSON_VALUE)
    public APIResponse<InquiryOrderEntity> getInquiryOrder(@RequestParam String ioNum) {
        InquiryOrderEntity inquiryOrder = inquiryOrderSV.selectOne(
                TK.select(InquiryOrderEntity.class)
                        .where()
                        .andEqualTo(InquiryOrderEntity::getIoNum, ioNum)
                        .end()
        );
        return successData(inquiryOrder);
    }

    @Log
    @ApiOperation(value = "订单-退费申请", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/return/premium")
    public APIResponse returnPremium(@RequestBody OrderParam orderModel) {
        orderPaySV.refundOrder(orderModel);
        return success();
    }

    @Log
    @ApiOperation("订单-提现申请")
    @PostMapping(value = "/withdraw", consumes = MediaType.APPLICATION_JSON_VALUE)
    public APIResponse withdraw(@RequestBody String outTradeNo) {
        orderPaySV.withdraw(outTradeNo);
        return success();
    }

    @Log
    @ApiOperation("问诊订单退款回调修改订单信息")
    @PostMapping(value = "/orderRefundCallback")
    public APIResponse refundQuery(@RequestBody @Valid WxNotifyRespData wxNotifyRespData) {
        InquiryOrderEntity order = (InquiryOrderEntity) getInquiryOrder(wxNotifyRespData.getIoNum()).getData();
        order.setPaymentTime(DateUtil.parse(wxNotifyRespData.getSuccessTime(), "yyyyMMddHHmmss"));
        orderPaySV.wxrefundUpdateOrderInfo(order, wxNotifyRespData.getTransactionId());
        return successMsg("该订单退款成功");
    }


    @Log
    @ApiOperation("申诉退费订单退款回调修改订单信息")
    @PostMapping(value = "/complainOrderRefundCallback")
    public APIResponse complainOrderRefundCallback(@RequestBody @Valid WxNotifyRespData wxNotifyRespData) {
        //根据订单号获取订单信息
        InquiryOrderEntity order = (InquiryOrderEntity) getInquiryOrder(wxNotifyRespData.getIoNum()).getData();
        order.setPaymentTime(DateUtil.parse(wxNotifyRespData.getSuccessTime(), "yyyyMMddHHmmss"));
        orderPaySV.complainOrderRefund(order, wxNotifyRespData.getTransactionId());
        return successMsg("该订单退款成功");
    }

    @Log
    @ApiOperation("订单-更新信息 包括订单的状态更新")
    @PostMapping(value = "/update", consumes = MediaType.APPLICATION_JSON_VALUE)
    public APIResponse updateInquiryOrder(@RequestBody OrderAndFileParam inquiryOrder) {
        boolean flag = inquiryOrderSV.updateInquiryOrder(inquiryOrder);
        if (flag) {
            return successData(inquiryOrder);
        }
        return failMsg("订单信息更新失败！");
    }

    @Log
    @ApiOperation("新增个人消费明细")
    @PostMapping(value = "/consume/detail/add")
    public APIResponse insertConsumeDetail(@RequestBody ConsumeDetailsEntity consumeDetails) {
        consumeDetails.setAccId(ShiroUtil.getLoginId(true));
        consumeDetailsSV.insert(consumeDetails);
        return failMsg("新增个人消费明细失败");
    }

    @Log
    @ApiOperation("回调送心意")
    @PostMapping(value = "/mindOrderPayCallBack")
    public APIResponse mindOrderPayCallBack(@RequestBody @Valid WxNotifyRespData wxNotifyRespData) {
        LOGGER.info("----------------------------------------送心意支付回调成功  url:{}---------------------------------------------------", "/mindOrderPayCallBack");
        MindListMobileVO mindModel = mindSV.getMindModelByIoNum(wxNotifyRespData.getIoNum());
        mindModel.setTdTime(DateUtil.parse(wxNotifyRespData.getTimeEnd(), "yyyyMMddHHmmss"));
        orderPaySV.updateMindOrder(mindModel, wxNotifyRespData.getTransactionId());
        return successMsg("送心意订单支付成功");
    }

    @Log
    @ApiOperation("充值回调接口")
    @RequestMapping(value = "/rechargeCallBack", method = RequestMethod.POST)
    public APIResponse RechargeCallBack(@RequestBody @Valid WxNotifyRespData wxNotifyRespData) {
        LOGGER.info("----------------------------------------充值回调成功  url:{}---------------------------------------------------", "/mindOrderPayCallBack");
        MindListMobileVO mindModel = mindSV.getMindModelByIoNum(wxNotifyRespData.getIoNum());
        mindModel.setTdTime(DateUtil.parse(wxNotifyRespData.getTimeEnd(), "yyyyMMddHHmmss"));
        orderPaySV.updateMindOrder(mindModel, wxNotifyRespData.getTransactionId());
        return successMsg("充值订单支付成功");
    }

    @Log
    @ApiOperation("订单-主动取消未支付订单")
    @PostMapping(value = "/cancel/order", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public APIResponse cancelOrder(
            @NotNull Long orderId
    ) {
        inquiryOrderSV.unPayCancelOrder(orderId, OrderFlowRecordSatusEnum.THE_CANCELLATION, InquiryOrderStateEnum.VOIDED);
        return success();
    }



}
